import { useEffect, useRef, useState, useMemo } from 'react';
import {
    getSuitableZoomNumber,
    setMarkers,
    getAreaBoundaries,
    generateMask,
    generatePolyline,
    showMarkerInfo
} from '@/utils/map.utils'
import { useRecoilValue } from 'recoil';
import { homeState } from '@/store'
import { KUN_SHAN_CENTER } from '@/constants/map.constants'
import { useHomeContext } from '@/pages/home/useHomeContext'
import customMapConfig from '@/data/custom_map_config.json'

import styles from './styles.module.css';

type Points = [number, number][];

const CustomMap = () => {
    const mapRef = useRef(null);
    const [mapInstance, setMapInstance] = useState<BMapGL.Map | null>(null);
    const { elevators } = useRecoilValue(homeState);
    const [points, setPoints] = useState<Points>([])
    const { homeContext } = useHomeContext();

    const alerts: Alert[] = useMemo(() => {
        return elevators.map(((item: any) => ({
            point: [item.lng, item.lat],
            info: item,
            // 弄一个warning的假数据
            status: item.id === '01589f278cc340cab7571ef994124849' ? 'warning' : 'running'
        })))
    }, [elevators])

    useEffect(() => {
        if (!mapInstance || !points.length) {
            return;
        }

        // 添加路径代码
        // const polyline = new BMapGL.Polyline(
        //     points.map(point => new BMapGL.Point(...point)),
        //     {
        //         strokeColor: "red",
        //         strokeWeight: 3,
        //         strokeOpacity: 0.5
        //     }
        // );

        // const [first, last] = [points[0], points[points.length - 1]];

        // mapInstance?.addOverlay(polyline);
        // mapInstance?.setCenter(new BMapGL.Point((first[0] + last[0]) / 2, (last[1] + last[1]) / 2))

        // 自动寻路代码
        const driving = new BMapGL.DrivingRoute(mapInstance, {
            renderOptions: {
                map: mapInstance,
                autoViewport: true,
            },
            onMarkersSet: function (routes) {
                mapInstance.removeOverlay(routes[0].marker); //删除起点
                mapInstance.removeOverlay(routes[routes.length - 1].marker); //删除终点
            },
            onPolylinesSet: function (routes) {
                routes.forEach(route => {
                    mapInstance.removeOverlay(route.getPolyline())
                })
            },
        });
        driving.setSearchCompleteCallback(function () {
            const plan = driving.getResults().getPlan(0);

            for (let i = 0; i < plan.getNumRoutes(); i++) {
                const pts = plan.getRoute(i).getPath();

                const polyline = new BMapGL.Polyline(pts, { strokeColor: "#f9b531", strokeWeight: 2, strokeOpacity: 1 });

                mapInstance.addOverlay(polyline);
            }
        })

        driving.search(new BMapGL.Point(...points[0]), new BMapGL.Point(...points[1]));
    }, [mapInstance, points])

    useEffect(() => {
        if (mapInstance && alerts?.length) {
            setMarkers({
                map: mapInstance,
                items: alerts,
                getMarkerPosition: ({ point }) => point,
                getStatus: ({ status }) => status,
                showInfo: showMarkerInfo(mapInstance),
                markerCategories: {
                    running: !!homeContext?.homeData?.markerCategories?.running,
                    warning: !!homeContext?.homeData?.markerCategories?.warning,
                    inMaintenance: !!homeContext?.homeData?.markerCategories?.inMaintenance,
                    rescueSite: !!homeContext?.homeData?.markerCategories?.rescueSite,
                    rescuedToday: !!homeContext?.homeData?.markerCategories?.rescuedToday
                },
                isDetailPage: true
            });
        }
    }, [mapInstance, alerts, homeContext?.homeData?.markerCategories])

    useEffect(() => {
        setPoints([
            [120.94068976733922, 31.517322801712705],
            [120.9206, 31.41732280171270]]
        );
    }, [])

    useEffect(() => {
        setTimeout(() => {
            if (window.BMAP_INSTANCE_IN_DETAIL_PAGE || !mapRef.current) return;

            window.BMAP_INSTANCE_IN_DETAIL_PAGE = new BMapGL.Map(mapRef.current);
            window.BMAP_INSTANCE_IN_DETAIL_PAGE.centerAndZoom(new BMapGL.Point(...KUN_SHAN_CENTER), getSuitableZoomNumber() - 3);
            window.BMAP_INSTANCE_IN_DETAIL_PAGE.setMapStyleV2({ styleJson: customMapConfig as BMapGL.MapStyleItem[] });

            (async (map: BMapGL.Map) => {
                const boundaryCoordinatePoints = await getAreaBoundaries('昆山市');

                map.addOverlay(generateMask(boundaryCoordinatePoints));
                map.addOverlay(generatePolyline(boundaryCoordinatePoints));
                setMapInstance(window.BMAP_INSTANCE_IN_DETAIL_PAGE);
            })(window.BMAP_INSTANCE_IN_DETAIL_PAGE)
        }, 300)

        return () => {
            window.BMAP_INSTANCE_IN_DETAIL_PAGE = null;
        }
    }, [mapRef.current])

    return (
        <div className={styles.container} ref={mapRef}></div>
    )
}

export default CustomMap;